import React, { Component } from 'react'

// 装饰器它是es7提出来的，目前还没有正式的支持，需要配置向下兼容
// 装饰器它是用来装饰类的  ==> 对于已有类，不去修改它的代码的情况下，就可以添加或修改已有方法或属性

// 1.装饰类,调用时没有写小括号
/*// target就是当前的装饰的类
const fn = Target => {
  // 添加成员属性
  Target.prototype.username = '李四'
  Target.prototype.run = function(){
    console.log('run')
  }
}
@fn
class Demo {
  id = 100
}
let demo = new Demo()
console.log(demo.username)
demo.run()
 */

// 2.装饰类,调用时有写小括号
// target就是当前的装饰的类
/* const fn = username => Target => {
  // 添加成员属性
  Target.prototype.username = username
}
@fn('张三')
class Demo {
  id = 100
}
let demo = new Demo()
console.log(demo.username) */

// 3.装饰成员属性 不写小括号
/* // target 当前装饰类的实例对象   类的this
// key 当前装饰属性的名称
// description 当前属性在当前对象中的描述  Object.defineProperty 对象
const readonly = (target, key, description) => {
  // console.log(target, key, description)
  // 让当前属性变成只读
  description['writable'] = false
}

class Demo {
  @readonly
  id = 100
}
let demo = new Demo()
// demo.id = 2000 // 只读后，修改就会报错
console.log(demo.id)
 */

// 4.装饰成员属性 写小括号
/* // target 当前装饰类的实例对象   类的this
// key 当前装饰属性的名称
// description 当前属性在当前对象中的描述  Object.defineProperty 对象
const readonly = flag => (target, key, description) => {
  // 让当前属性变成只读
  description['writable'] = flag
}

class Demo {
  @readonly(false)
  id = 100
}
let demo = new Demo()
// demo.id = 2000 // 只读后，修改就会报错
console.log(demo.id) */

// 5.装饰类中的成员方法
const fn = (target, key, description) => {

  // this在后续调用时，解决它的this指向
  let oldFn = description.value

  description.value = function (...args) {
    // oldFn.call(this,...args)
    oldFn.apply(this, args)
    // 装饰后的方法
    console.log('我是之前没有，现在添加的方法')
  }
}

class Demo {
  
  id = 100

  /* @fn
  run(...args) {
    console.log('run -- ', this.id, args)
  } */
  @fn run(...args) {
    console.log('run -- ', this.id, args)
  }
}
let demo = new Demo()
demo.run(1, 2, 3)




class App extends Component {
  render() {
    return <div>App</div>
  }
}

export default App
